function ajax(time){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            if(time>5000){//只是模拟失败
                reject()
            }
            resolve()
        },time)
    })
}
class Limit{
    constructor(parallCount=2){//最大并发量（默认值为2）
        this.task=[]//任务队列
        this.parallCount=parallCount//最大并发量,同时使得函数也可以使用parallCount
        this.runningCount=0//当前运行的任务数量
    }
    add(task){
        return new Promise((resolve,reject)=>{
            this.task.push({
                task,
                resolve,
                reject
            })//添加任务到任务队列,resolve和reject用于处理任务的完成和失败
            this._run()
        })
    }
    _run(){
        if(this.runningCount<this.parallCount&&this.task.length){//正在运行的任务量小于数列任务量且任务队列内还有任务
            const {task,resolve,reject}=this.task.shift()//从任务队列中取出一个任务
            this.runningCount++
            task().then(()=>{//检查任务是否完成
                resolve()
                this.runningCount--//任务完成后，当前运行的任务数量减一
                this._run()//递归
            }).catch(()=>{//任务失败
                reject()
                this.runningCount--//任务完成后，当前运行的任务数量减一
                this._run()//递归
            })
            //或者用一下方式
            // task.then(resolve,reject).finally(()=>{//任务完成或失败，都需要调用run函数，递归执行
            //     this.runningCount--//任务完成后，当前运行的任务数量减一
            //     this._run()
            // })
        }
    }
}
const limit=new Limit(3)
function addTask(time,name){
    limit.add(()=>ajax(time)).then(()=>{
        console.log(`任务${name}完成`);
    }).catch(()=>{
        console.log(`任务${name}失败`);
    })
}
addTask(10000,1)
addTask(4000,2)
addTask(2000,3)
addTask(7000,4)
addTask(1000,5)